<?php

namespace app\service;

use app\common\BaseService;
use app\model\Allocation as AllocationModel;
use app\model\AllocationOrder as AllocationOrderModel;
use app\service\StoreService;
use think\facade\Db;

class AllocationService extends BaseService
{
  public static function getInstance(): AllocationService
  {
    return parent::getInstance();
  }

  public static function getModel(): AllocationOrderModel
  {
    return AllocationOrderModel::getInstance();
  }
  public static function getDetailModel(): AllocationModel
  {
    return AllocationModel::getInstance();
  }

  public static function getDataByCondition($conditions, $order = ['id' => 'desc']) {
    return self::getModel()->getDataByCondition($conditions, $order);
  }

  // 新增
  public function createAllocation($data) {
    // 获取调拨申请号
    $cond = [
      ['insert_time', date('Y-m-d'), '>=']
    ];
    $all = self::getModel()->getDataByCondition($cond);
    $arr = array_unique(array_column($all, 'apply_number'));
    $num = str_pad(count($arr) + 1, 3, '0', STR_PAD_LEFT);
    $applyNumber = 'DB'.date('Ymd') . $num;
    // 新增调拨信息
    $insertAllocation = [];
    $insertAllocationOrder = [
      'apply_number' => $applyNumber,
      'allocation_time' => $data['allocation_time'],
      'base_from' => $data['base_from'],
      'base_to' => $data['base_to'],
      'comment' => '',
      'status' => 2,
      'insert_time' => date('Y-m-d H:i:s'),
      'last_update_time' => date('Y-m-d H:i:s')
    ];

    // 获取A门店仓库数据
    $condA = [
      ['status', 1, '='],
      ['base', $data['base_from'], '=']
    ];
    $houseFrom = StoreService::getInstance()->getDataByCondition($condA);
    $houseFrom = array_column($houseFrom, null, 'id');

    foreach ($data['detail'] as $value) {
      // 数据是否存在
      if (isset($houseFrom[$value['store_from']])) {
        // 查找门店A数据
        $from = $houseFrom[$value['store_from']];
        // 新增详情数据
        $insertAllocation[] = [
          'allocation_order_id' => '',
          'count' => $value['count'],
          'store_from' => $from['id'],
          'comment' => $value['comment'],
          'status' => 1,
          'insert_time' => date('Y-m-d H:i:s'),
          'last_update_time' => date('Y-m-d H:i:s')
        ];
      } else {
        return ['status' => false, 'msg' => '商品有误'];
      }
    }

    self::getModel()->startTrans();
    try {
      // 新增allocation_order
      if ($insertAllocationOrder) {
        $res = self::getModel()
          ->insertGetId($insertAllocationOrder);
        if ($res === false) {
          throw new \Exception('新增allocation_order失败');
        }
      }
      // 新增allocation
      if ($insertAllocation) {
        foreach ($insertAllocation as &$v) {
          $v['allocation_order_id'] = $res;
        }
        $res1 = self::getDetailModel()->insertAll($insertAllocation);
        if (!$res1) {
          throw new \Exception('新增allocation失败');
        }
      }
      self::getModel()->commit();
      return ['status' => true, 'msg' => 'ok'];
    } catch (\Exception $e) {
      self::getModel()->rollback();
      return ['status' => false, 'msg' => $e->getMessage()];
    }
  }

  // 获取详情
  public function getAllocationJoinStore($conditions, $order = ['a.id' => 'DESC']) {
    $conditions[] = ['a.status', 1, '='];
    $query = Db::name('allocation')
      ->alias('a')
      ->field('a.*, ao.apply_number, ao.allocation_time, ao.comment as order_comment, ao.base_to, s.name, s.unit, s.category_id, c.category_name')
      ->join('store_house s', 's.id = a.store_from', 'LEFT')
      ->join('allocation_order ao', 'ao.id = a.allocation_order_id', 'LEFT')
      ->join('category c', 'c.id = s.category_id', 'LEFT');
    foreach ($conditions as $item) {
      list($field, $value, $op) = $item;
      if (!$op) {
        $op = '=';
      }
      $query = $query->where($field, $op, $value);
    }
    $query = $query->order($order);
    return $query->select()->toArray();
  }

  // 编辑
  public function updateMulti($id, $data) {
    // 获取原数据
    $allocation = self::getModel()->find($id)->toArray();
    // 更新调拨信息
    $insertAllocation = [];
    $updateAllocationOrder = [
      'allocation_time' => $data['allocation_time'],
      'base_from' => $data['base_from'],
      'comment' => '',
      'last_update_time' => date('Y-m-d H:i:s')
    ];
    if ($allocation['status'] != 3) {
      $updateAllocationOrder['status'] = 2;
    }
    // 获取A门店仓库数据/分类
    $condA = [
      ['status', 1, '='],
      ['base', $allocation['base_from'], '=']
    ];
    $houseFrom = StoreService::getInstance()->getDataByCondition($condA);
    $houseFrom = array_column($houseFrom, null, 'id');
    // 新增调拨信息
    foreach ($data['detail'] as $value) {
      // 数据是否存在
      if (isset($houseFrom[$value['store_from']])) {
//        // 查找门店A数据
        $from = $houseFrom[$value['store_from']];
        // 新增详情数据
        $insertAllocation[] = [
          'allocation_order_id' => $id,
          'count' => $value['count'],
          'store_from' => $from['id'],
          'comment' => $value['comment'],
          'status' => 1,
          'insert_time' => date('Y-m-d H:i:s'),
          'last_update_time' => date('Y-m-d H:i:s')
        ];
      } else {
        return ['status' => false, 'msg' => '商品有误'];
      }
    }
    self::getModel()->startTrans();
    try {
      // 新增allocation_order
      if ($updateAllocationOrder) {
        $res = self::getModel()->where('id', '=', $id)->save($updateAllocationOrder);
        if ($res === false) {
          throw new \Exception('新增allocation_order失败');
        }
      }
      // 删除allocation
      if ($insertAllocation) {
        $res1 = self::getDetailModel()->where('allocation_order_id', '=', $id)->delete();
        if ($res1 === false) {
          throw new \Exception('删除allocation失败');
        }
        $res2 = self::getDetailModel()->insertAll($insertAllocation);
        if ($res2 === false) {
          throw new \Exception('新增allocation失败');
        }
      }
      self::getModel()->commit();
      return ['status' => true, 'msg' => 'ok'];
    } catch (\Exception $e) {
      self::getModel()->rollback();
      return ['status' => false, 'msg' => $e->getMessage()];
    }
  }

  // 审批
  public function checkAllocation($allocateId, $check, $comment) {
    // 修改allocation_order
    $updateAllocationOrder = [];
    // 修改allocation
    $updateAllocation = [];
    // 更新门店仓库
    $updateHouse = [];
    // 新增门店仓库
    $insertHouse = [];
    // 关联商品
    $connectProduct = [];
    // 通过审批
    if ($check) {
      // 获取申请单
      $allocate = self::getModel()->find($allocateId)->toArray();
      // 获取详情
      $detail = self::getDetailModel()->where('allocation_order_id', '=', $allocateId)->select()->toArray();
      // 运营通过
      if ($allocate['status'] === 2) {
        $updateAllocationOrder = [
          'status' => 3,
          'last_update_time' => date('Y-m-d H:i:s')
        ];
      }
      // 仓管通过
      else if ($allocate['status'] === 3){
        $updateAllocationOrder = [
          'status' => 1,
          'last_update_time' => date('Y-m-d H:i:s')
        ];
        // 获取A门店仓库数据/分类
        $condA = [
          ['status', 1, '='],
          ['base', $allocate['base_from'], '=']
        ];
        $houseFrom = StoreService::getInstance()->getDataByCondition($condA);
        $houseFrom = array_column($houseFrom, null, 'id');
        $categoryFrom = CategoryService::getInstance()->getCategoryByCondition($condA);
        $categoryFrom = array_column($categoryFrom, null, 'id');
        // 获取B门店仓库数据/分类
        $condB = [
          ['status', 1, '='],
          ['base', $allocate['base_to'], '=']
        ];
        $categoryTo = CategoryService::getInstance()->getCategoryByCondition($condB);
        $houseTo = StoreService::getInstance()->getDataByCondition($condB);
        $houseTo = array_column($houseTo, null, 'name');
        $categoryTo = array_column($categoryTo, null, 'category_name');
        foreach ($detail as $value) {
          // 数据是否存在
          if (isset($houseFrom[$value['store_from']])) {
            // 查找门店A数据
            $from = $houseFrom[$value['store_from']];
            if ($from['count'] < $value['count']) {
              return ['status' => false, 'msg' => '商品：'.$from['name'].'数量不足'];
            }
            $updateHouse[] = [
              'id' => $from['id'],
              'count' => round($from['count'] - $value['count'], 2),
              'total_amount' => round(($from['count'] - $value['count']) * $from['price'], 2)
            ];
            // 门店A分类
            $fromCat = isset($categoryFrom[$from['category_id']]) ? $categoryFrom[$from['category_id']] : 0;
            if (!$fromCat) {
              return ['status' => false, 'msg' => '商品：'.$from['name'].'分类有误'];
            }
            $catName = $fromCat['category_name'];
            if (!isset($categoryTo[$catName])) {
              return ['status' => false, 'msg' => '分类：'.$catName.'在调拨门店中不存在'];
            }
            // 更新门店B数据
            if (isset($houseTo[$from['name']])) {
              $to = $houseTo[$from['name']];
              $updateHouse[] = [
                'id' => $to['id'],
                'count' => round($to['count'] + $value['count'], 2),
                'total_amount' => round(($to['count'] + $value['count']) * $to['price'], 2)
              ];
              $updateAllocation[] = [
                'id' => $value['id'],
                'store_to' => $to['id']
              ];
            } else {
              $insertHouse[] = [
                'goods_id' => $from['goods_id'],
                'category_id' => $categoryTo[$catName]['id'],
                'name' => $from['name'],
                'price' => $from['price'],
                'count' => $value['count'],
                'total_amount' => round($from['price'] * $value['count'], 2),
                'base' => $allocate['base_to'],
                'unit' => $from['unit'],
                'status' => 1,
                'insert_time' => date('Y-m-d H:i:s'),
                'last_update_time' => date('Y-m-d H:i:s'),
              ];
              $connectProduct[$from['name']] = $value['id'];
            }
          }
        }
      }
    }
    // 驳回
    else {
      $updateAllocationOrder = [
        'status' => 4,
        'comment' => $comment,
        'last_update_time' => date('Y-m-d H:i:s')
      ];
    }
    self::getModel()->startTrans();
    try {
      // 修改allocation_order
      if ($updateAllocationOrder) {
        $res = self::getModel()->where('id', '=', $allocateId)->save($updateAllocationOrder);
        if ($res === false) {
          throw new \Exception('修改allocation_order失败');
        }
      }
      // 新增store_house
      if ($insertHouse) {
        foreach ($insertHouse as $ihv) {
          if (isset($connectProduct[$ihv['name']])) {
            $allocateId = $connectProduct[$ihv['name']];
            if (!$allocateId) {
              continue;
            }
            $res2 = StoreService::getModel()->insertGetId($ihv);
            if ($res2 === false) {
              throw new \Exception('新增store_house失败');
            }
            if ($res2) {
              $res3 = self::getDetailModel()->where('id', '=', $allocateId)->save(['store_to' => $res2]);
              if ($res3 === false) {
                throw new \Exception('修改allocation失败');
              }
            }
          }
        }
      }
      // 修改store_house
      if ($updateHouse) {
        $res4 = StoreService::getModel()->saveAll($updateHouse);
        if ($res4 === false) {
          throw new \Exception('修改store_house失败');
        }
      }
      //  修改allocation
      if ($updateAllocation) {
        $res5 = AllocationService::getDetailModel()->saveAll($updateAllocation);
        if ($res5 === false) {
          throw new \Exception('修改allocation失败');
        }
      }
      self::getModel()->commit();
      return ['status' => true, 'msg' => 'ok'];
    } catch (\Exception $e) {
      self::getModel()->rollback();
      return ['status' => false, 'msg' => $e->getMessage()];
    }
  }

  // 删除
  public function deleteAllocation($id) {
    // 获取申请单
    $allocate = self::getModel()->find($id)->toArray();
    // 获取详情
    $detail = self::getDetailModel()->where('allocation_order_id', '=', $id)->select()->toArray();
    // 修改allocation
    $updateAllocation = [
      'status' => 0,
      'last_update_time' => date('Y-m-d H:i:s')
    ];
    // 修改house
    $updateHouse = [];

    // 仓管删除（回滚）
    if ($allocate['status'] === 1) {
      // 获取A门店仓库数据
      $condA = [
        ['status', 1, '='],
        ['base', $allocate['base_from'], '=']
      ];
      $houseFrom = StoreService::getInstance()->getDataByCondition($condA);
      $houseFrom = array_column($houseFrom, null, 'id');
      // 获取B门店仓库数据
      $condB = [
        ['status', 1, '='],
        ['base', $allocate['base_to'], '=']
      ];
      $houseTo = StoreService::getInstance()->getDataByCondition($condB);
      $houseTo = array_column($houseTo, null, 'id');
      foreach ($detail as $value) {
        // 数据是否存在
        if (isset($houseFrom[$value['store_from']])) {
          // 查找门店A数据
          $from = $houseFrom[$value['store_from']];
          $updateHouse[] = [
            'id' => $from['id'],
            'count' => round($from['count'] + $value['count'], 2),
            'total_amount' => round(($from['count'] + $value['count']) * $from['price'], 2)
          ];
          // 更新门店B数据
          if (isset($houseTo[$value['store_to']])) {
            $to = $houseTo[$value['store_to']];
            if ($to['count'] < $value['count']) {
              return ['status' => false, 'msg' => '商品：'.$to['name'].'数量不足'];
            }
            $updateHouse[] = [
              'id' => $to['id'],
              'count' => round($to['count'] - $value['count'], 2),
              'total_amount' => round(($to['count'] - $value['count']) * $to['price'], 2)
            ];
          } else {
            return ['status' => false, 'msg' => '商品：'.$from['name'].'在调拨门店不存在'];
          }
        } else {
          return ['status' => false, 'msg' => '商品ID：'.$value['store_id'].'的商品有误'];
        }
      }
    }
    self::getModel()->startTrans();
    try {
      // 修改allocation_order
      $res = self::getModel()->where('id', '=', $id)->save($updateAllocation);
      if ($res === false) {
        throw new \Exception('修改allocation_order失败');
      }
      // 修改allocation
      $res1 = self::getDetailModel()->where('allocation_order_id', '=', $id)->save($updateAllocation);
      if ($res1 === false) {
        throw new \Exception('修改allocation_order失败');
      }
      // 修改store_house
      if ($updateHouse) {
        $res3 = StoreService::getModel()->saveAll($updateHouse);
        if ($res3 === false) {
          throw new \Exception('修改store_house失败');
        }
      }
      self::getModel()->commit();
      return ['status' => true, 'msg' => 'ok'];
    } catch (\Exception $e) {
      self::getModel()->rollback();
      return ['status' => false, 'msg' => $e->getMessage()];
    }
  }
}